using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace FileSystemDialogs
{
    // 存储选择结果的数据类
    public class FileDirectorySelection
    {
        public List<string> Files { get; } = new List<string>();
        public List<string> Directories { get; } = new List<string>();
    }

    // 主对话框类
    public class FileDirectoryPicker : Form
    {
        private TreeView tvFileSystem;
        private CheckBox chkAllowFiles;
        private CheckBox chkAllowDirs;
        private TextBox txtFilter;
        private Button btnOK;
        private Button btnCancel;
        private FileDirectorySelection selectionResult;

        // 公共属性
        public string Filter { get; set; } = "所有文件 (*.*)|*.*";
        public bool AllowMultiSelect { get; set; } = true;
        public bool ShowHiddenItems { get; set; } = false;

        public FileDirectoryPicker()
        {
            selectionResult = new FileDirectorySelection();
            InitializeUI();
            LoadDrives();
        }

        private void InitializeUI()
        {
            // 窗体设置
            Text = "选择文件和目录";
            Size = new Size(800, 600);
            StartPosition = FormStartPosition.CenterScreen;
            FormBorderStyle = FormBorderStyle.FixedDialog;
            MaximizeBox = false;

            // 创建控件
            var pnlFilter = new Panel { Dock = DockStyle.Top, Height = 40 };
            var lblFilter = new Label { Text = "筛选器:", Dock = DockStyle.Left, Width = 60, Margin = new Padding(5) };
            txtFilter = new TextBox { Dock = DockStyle.Fill, Margin = new Padding(5), Text = Filter };
            txtFilter.TextChanged += (s, e) => RefreshCurrentView();

            var pnlOptions = new Panel { Dock = DockStyle.Top, Height = 30 };
            chkAllowFiles = new CheckBox { Text = "允许选择文件", Checked = true, Dock = DockStyle.Left, Width = 120 };
            chkAllowDirs = new CheckBox { Text = "允许选择目录", Checked = true, Dock = DockStyle.Left, Width = 120 };
            chkAllowFiles.CheckedChanged += (s, e) => RefreshCurrentView();
            chkAllowDirs.CheckedChanged += (s, e) => RefreshCurrentView();

            tvFileSystem = new TreeView
            {
                Dock = DockStyle.Fill,
                CheckBoxes = true,
                ShowLines = true,
                ShowPlusMinus = true,
                ImageList = new ImageList()
            };
            tvFileSystem.ImageList.Images.Add("folder", SystemIcons.Warning.ToBitmap());
            tvFileSystem.ImageList.Images.Add("file", SystemIcons.Error.ToBitmap());
            tvFileSystem.BeforeExpand += TvFileSystem_BeforeExpand;
            tvFileSystem.AfterCheck += TvFileSystem_AfterCheck;

            var pnlButtons = new Panel { Dock = DockStyle.Bottom, Height = 40 };
            btnOK = new Button { Text = "确定", DialogResult = DialogResult.OK, Width = 75, Location = new Point(600, 5) };
            btnCancel = new Button { Text = "取消", DialogResult = DialogResult.Cancel, Width = 75, Location = new Point(680, 5) };

            // 组装控件
            pnlFilter.Controls.Add(txtFilter);
            pnlFilter.Controls.Add(lblFilter);
            pnlOptions.Controls.Add(chkAllowDirs);
            pnlOptions.Controls.Add(chkAllowFiles);
            pnlButtons.Controls.Add(btnCancel);
            pnlButtons.Controls.Add(btnOK);

            Controls.Add(pnlButtons);
            Controls.Add(tvFileSystem);
            Controls.Add(pnlOptions);
            Controls.Add(pnlFilter);

            // 关闭时收集结果
            FormClosing += (s, e) =>
            {
                if (DialogResult == DialogResult.OK)
                {
                    CollectSelection();
                }
            };
        }

        // 加载系统驱动器
        private void LoadDrives()
        {
            try
            {
                foreach (var drive in DriveInfo.GetDrives())
                {
                    if (drive.IsReady)
                    {
                        var node = new TreeNode(drive.Name)
                        {
                            Tag = drive.RootDirectory.FullName,
                            ImageKey = "folder",
                            SelectedImageKey = "folder"
                        };
                        tvFileSystem.Nodes.Add(node);
                        AddChildNodes(node); // 加载一级子项
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"加载驱动器失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 添加子节点（文件和目录）
        private void AddChildNodes(TreeNode parent)
        {
            try
            {
                string path = parent.Tag.ToString();
                
                // 添加目录
                if (chkAllowDirs.Checked)
                {
                    foreach (var dir in Directory.GetDirectories(path))
                    {
                        if (!ShowHiddenItems && (new DirectoryInfo(dir).Attributes & FileAttributes.Hidden) != 0)
                            continue;

                        var node = new TreeNode(Path.GetFileName(dir))
                        {
                            Tag = dir,
                            ImageKey = "folder",
                            SelectedImageKey = "folder"
                        };
                        parent.Nodes.Add(node);
                        node.Nodes.Add(new TreeNode()); // 占位符
                    }
                }

                // 添加文件
                if (chkAllowFiles.Checked)
                {
                    foreach (var file in GetFilteredFiles(path))
                    {
                        if (!ShowHiddenItems && (new FileInfo(file).Attributes & FileAttributes.Hidden) != 0)
                            continue;

                        var node = new TreeNode(Path.GetFileName(file))
                        {
                            Tag = file,
                            ImageKey = "file",
                            SelectedImageKey = "file"
                        };
                        parent.Nodes.Add(node);
                    }
                }
            }
            catch
            {
                // 忽略无权限访问的项目
            }
        }

        // 根据筛选器获取文件
        private string[] GetFilteredFiles(string path)
        {
            try
            {
                string pattern = "*.*";
                if (!string.IsNullOrEmpty(txtFilter.Text))
                {
                    var parts = txtFilter.Text.Split('|');
                    if (parts.Length >= 2)
                        pattern = parts[1];
                }
                return Directory.GetFiles(path, pattern);
            }
            catch
            {
                return Array.Empty<string>();
            }
        }

        // 展开节点时加载子项
        private void TvFileSystem_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            var node = e.Node;
            if (node.ImageKey == "folder" && node.Nodes.Count > 0 && node.Nodes[0].Tag == null)
            {
                node.Nodes.Clear();
                AddChildNodes(node);
            }
        }

        // 处理勾选事件
        private void TvFileSystem_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.Unknown || !AllowMultiSelect)
                return;

            // 目录勾选时自动勾选所有子项
            if (e.Node.ImageKey == "folder" && e.Node.Checked)
            {
                foreach (TreeNode child in e.Node.Nodes)
                {
                    child.Checked = true;
                }
            }
        }

        // 收集选中的项目
        private void CollectSelection()
        {
            selectionResult.Files.Clear();
            selectionResult.Directories.Clear();
            CollectNodes(tvFileSystem.Nodes);
        }

        // 递归收集节点
        private void CollectNodes(TreeNodeCollection nodes)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Checked)
                {
                    if (node.ImageKey == "folder" && chkAllowDirs.Checked)
                    {
                        selectionResult.Directories.Add(node.Tag.ToString());
                    }
                    else if (node.ImageKey == "file" && chkAllowFiles.Checked)
                    {
                        selectionResult.Files.Add(node.Tag.ToString());
                    }
                }

                if (node.Nodes.Count > 0)
                {
                    CollectNodes(node.Nodes);
                }
            }
        }

        // 刷新当前视图
        private void RefreshCurrentView()
        {
            foreach (TreeNode node in tvFileSystem.Nodes)
            {
                node.Nodes.Clear();
                AddChildNodes(node);
            }
        }

        // 显示对话框的静态方法
        public static FileDirectorySelection Show()
        {
            using (var dialog = new FileDirectoryPicker())
            {
                return dialog.ShowDialog() == DialogResult.OK ? dialog.selectionResult : new FileDirectorySelection();
            }
        }
    }

    // 使用示例
    public class DemoForm : Form
    {
        public DemoForm()
        {
            var btnSelect = new Button
            {
                Text = "选择文件和目录",
                Location = new Point(50, 50),
                Size = new Size(150, 30)
            };
            btnSelect.Click += (s, e) =>
            {
                var result = FileDirectoryPicker.Show();
                MessageBox.Show(
                    $"已选择 {result.Files.Count} 个文件和 {result.Directories.Count} 个目录",
                    "选择结果"
                );
            };
            Controls.Add(btnSelect);
            Size = new Size(300, 200);
        }
    }
}
